package services

import (
	"bbs-go/internal/consts"
	"strconv"

	"github.com/mlogclub/simple/sqls"
	"github.com/mlogclub/simple/web/params"
	"gorm.io/gorm"

	"bbs-go/internal/models"
	"bbs-go/internal/repositories"
)

var ChatFriendsRequestService = newChatFriendsRequestService()

func newChatFriendsRequestService() *chatFriendsRequestService {
	return &chatFriendsRequestService{}
}

type chatFriendsRequestService struct {
}

func (s *chatFriendsRequestService) Get(id int64) *models.ChatFriendsRequest {
	return repositories.ChatFriendsRequestRepository.Get(sqls.DB(), id)
}

func (s *chatFriendsRequestService) Take(where ...interface{}) *models.ChatFriendsRequest {
	return repositories.ChatFriendsRequestRepository.Take(sqls.DB(), where...)
}

func (s *chatFriendsRequestService) Find(cnd *sqls.Cnd) []models.ChatFriendsRequest {
	return repositories.ChatFriendsRequestRepository.Find(sqls.DB(), cnd)
}

func (s *chatFriendsRequestService) FindPageByParams(params *params.QueryParams) (list []models.ChatFriendsRequest, paging *sqls.Paging) {
	return repositories.ChatFriendsRequestRepository.FindPageByParams(sqls.DB(), params)
}

func (s *chatFriendsRequestService) FindPageByCnd(cnd *sqls.Cnd) (list []models.ChatFriendsRequest, paging *sqls.Paging) {
	return repositories.ChatFriendsRequestRepository.FindPageByCnd(sqls.DB(), cnd)
}

func (s *chatFriendsRequestService) Create(t *models.ChatFriendsRequest) error {
	return repositories.ChatFriendsRequestRepository.Create(sqls.DB(), t)
}

func (s *chatFriendsRequestService) Update(t *models.ChatFriendsRequest) error {
	return repositories.ChatFriendsRequestRepository.Update(sqls.DB(), t)
}

func (s *chatFriendsRequestService) Updates(id int64, columns map[string]interface{}) error {
	return repositories.ChatFriendsRequestRepository.Updates(sqls.DB(), id, columns)
}

func (s *chatFriendsRequestService) UpdateColumn(id int64, name string, value interface{}) error {
	return repositories.ChatFriendsRequestRepository.UpdateColumn(sqls.DB(), id, name, value)
}

// 查询是否已经申请过，并且是待审批
func (s *chatFriendsRequestService) GetChatFriendsRequestByFriendId(userId, friendId int64) (models.ChatFriendsRequest, error) {
	m := models.ChatFriendsRequest{}
	err := sqls.DB().Model(models.ChatFriendsRequest{}).Where("sender_user_id = ? and receiver_user_id = ? and status = ?", userId, friendId, consts.ChatFriendRequestStatus_1).Order("id asc").First(&m).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return models.ChatFriendsRequest{}, err
	}

	return m, nil
}

func (s *chatFriendsRequestService) RefuseFriendRequest(req *models.ChatFriendsRequest) error {
	err := sqls.DB().Model(models.ChatFriendsRequest{}).Where("id = ?", req.Id).Updates(
		map[string]interface{}{"status": consts.ChatFriendRequestStatus_2}).Error
	if err != nil {
		return err
	}

	return nil
}

func (s *chatFriendsRequestService) AgreeFriendRequest(req *models.ChatFriendsRequest) error {
	tx := sqls.DB().Begin()
	err := tx.Model(models.ChatFriendsRequest{}).Where("id = ?", req.Id).Updates(
		map[string]interface{}{"status": consts.ChatFriendRequestStatus_3}).Error
	if err != nil {
		tx.Rollback()
		return err
	}

	// 添加好友关系，添加两条数据
	chatFriend1 := &models.ChatFriends{
		UserId:   req.SenderUserId,
		FriendId: req.ReceiverUserId,
		Status:   1,
	}

	err = tx.Create(chatFriend1).Error
	if err != nil {
		tx.Rollback()
		return err
	}

	chatFriend2 := &models.ChatFriends{
		UserId:   req.ReceiverUserId,
		FriendId: req.SenderUserId,
		Status:   1,
	}

	err = tx.Create(chatFriend2).Error
	if err != nil {
		tx.Rollback()
		return err
	}

	err = tx.Commit().Error
	if err != nil {
		tx.Rollback()
		return err
	}
	return err
}

func (s *chatFriendsRequestService) GetRequestList(page *sqls.Paging, userId int64) (models.RequestListResponse, error) {
	limit := page.Limit
	offset := page.Limit * (page.Page - 1)
	if limit == 0 {
		limit = 10
	}
	db := sqls.DB()
	querySql := `select cfr.*,
	tu.nickname as user_nickname,tu.avatar as user_avatar,tu.email as user_email,tu.username as username
	from chat_friends_request cfr 
	left join t_user tu on cfr.sender_user_id = tu.id 
	where 1=1 and cfr.deleted_at is null `
	whereSql := ""
	whereVars := []interface{}{}

	whereSql += " and cfr.status = ? "
	whereVars = append(whereVars, consts.ChatFriendRequestStatus_1)

	whereSql += " and cfr.receiver_user_id = ? "
	whereVars = append(whereVars, userId)

	countSql := `select count(1)
	from chat_friends_request cfr 
	where 1=1 `

	var total int64
	err := db.Raw(countSql+whereSql, whereVars...).Scan(&total).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return models.RequestListResponse{}, err
	}

	list := []models.ChatFriendsRequestResponse{}
	orderBySql := " order by cfr.id desc LIMIT " + strconv.Itoa(limit) + " OFFSET " + strconv.Itoa(offset)
	err = db.Raw(querySql+whereSql+orderBySql, whereVars...).Find(&list).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return models.RequestListResponse{}, err
	}

	return models.RequestListResponse{
		List: list,
		Paging: &sqls.Paging{
			Page:  page.Page,
			Limit: page.Limit,
			Total: total,
		},
	}, nil
}

func (s *chatFriendsRequestService) GetMyRequestList(page *sqls.Paging, userId int64) (models.MyRequestListResponse, error) {
	limit := page.Limit
	offset := page.Limit * (page.Page - 1)
	if limit == 0 {
		limit = 10
	}
	db := sqls.DB()
	querySql := `select cfr.*,
	tu.nickname as user_nickname,tu.avatar as user_avatar,tu.email as user_email,tu.username as username
	from chat_friends_request cfr 
	left join t_user tu on cfr.receiver_user_id  = tu.id 
	where 1=1 and cfr.deleted_at is null `
	whereSql := ""
	whereVars := []interface{}{}

	whereSql += " and cfr.status <> ? "
	whereVars = append(whereVars, consts.ChatFriendRequestStatus_3)

	whereSql += " and cfr.sender_user_id = ? "
	whereVars = append(whereVars, userId)

	countSql := `select count(1)
	from chat_friends_request cfr 
	where 1=1 `

	var total int64
	err := db.Raw(countSql+whereSql, whereVars...).Scan(&total).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return models.MyRequestListResponse{}, err
	}

	list := []models.MyRequestResponse{}
	orderBySql := " order by cfr.id desc LIMIT " + strconv.Itoa(limit) + " OFFSET " + strconv.Itoa(offset)
	err = db.Raw(querySql+whereSql+orderBySql, whereVars...).Find(&list).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return models.MyRequestListResponse{}, err
	}

	return models.MyRequestListResponse{
		List: list,
		Paging: &sqls.Paging{
			Page:  page.Page,
			Limit: page.Limit,
			Total: total,
		},
	}, nil
}

func (s *chatFriendsRequestService) GetUntreatedRequestCount(userId int64) (int, error) {
	db := sqls.DB()
	whereSql := ""
	whereVars := []interface{}{}

	countSql := `select count(1)
	from chat_friends_request cfr 
	where 1=1 `

	whereSql += " and cfr.status = ? and cfr.receiver_user_id = ? "
	whereVars = append(whereVars, consts.ChatFriendRequestStatus_1)
	whereVars = append(whereVars, userId)

	var total int
	err := db.Raw(countSql+whereSql, whereVars...).Scan(&total).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return 0, err
	}

	return total, nil
}
